//
// Created by jaesonzhang on 2024/3/20.
//

#ifndef CPPSQLITE_THREADSAFEQUEUE_H
#define CPPSQLITE_THREADSAFEQUEUE_H

#include "queue"
#include "mutex"
#include "condition_variable"

template<typename T>
class ThreadSafeQueue {
public:
    void push(T value) {
        std::lock_guard<std::mutex> lock(mutex);
        queue.push(std::move(value));
        cv.notify_one();
    }

    bool try_pop(T &value) {
        std::lock_guard<std::mutex> lock(mutex);
        if (queue.empty()) {
            return false;
        }
        value = std::move(queue.front());
        queue.pop();
        return true;
    }

    bool wait_and_pop(T &value) {
        std::unique_lock<std::mutex> unique_lock(mutex);
        cv.wait(unique_lock, [this] { return !queue.empty(); });
        value = std::move(queue.front());
        queue.pop();
        return true;
    }

    bool empty() {
        std::lock_guard<std::mutex> lock(mutex);
        return queue.empty();
    }

private:
    mutable std::mutex mutex;
    std::queue<T> queue;
    std::condition_variable cv;
};


#endif //CPPSQLITE_THREADSAFEQUEUE_H
